[pull] main from MetaMask:main#743
Merged
pull[bot] merged 10 commits intoReality2byte:mainfrom May 8, 2026
Merged
Conversation
…tion (#29882) <!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until this PR meets the canonical Definition of Ready For Review in `docs/readme/ready-for-review.md`. In short: the template must be materially complete (not just section titles present), all status checks must be currently passing, and the only expected follow-up commits must be reviewer-driven. --> ## **Description** The .npmrc file configures npm's behavior for this project. Here's what each line does: ignore-scripts = true Prevents npm from automatically running lifecycle scripts (like preinstall, postinstall, prepare, etc.) defined in package.json of installed dependencies. This is a security measure — it stops potentially malicious packages from executing arbitrary code during installation. The tradeoff is that some packages that rely on build scripts (like native modules) won't set themselves up automatically, which is why this project uses yarn setup instead of a plain install. yes = false Disables automatic "yes" responses to prompts. This ensures npm will actually pause and ask for confirmation on interactive prompts rather than silently accepting defaults — useful to avoid unintended actions during scripted environments. offline = true Forces npm to only use the local cache and never hit the network. If a package isn't already cached, the install fails rather than fetching it. This is a reproducibility and security measure — it ensures installs are deterministic and prevents supply-chain attacks from packages being silently swapped on the registry. <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: ## **Related issues** Fixes: ## **Manual testing steps** ```gherkin Feature: my feature name Scenario: user [verb for user action] Given [describe expected initial app state] When user [verb for user action] Then [describe expected outcome] ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** <!-- Every checklist item must be consciously assessed before marking this PR as "Ready for review". A checked box means you deliberately considered that responsibility, not that you literally performed every action listed. Unchecked boxes are ambiguous: they are not an implicit "N/A" and they are not a silent "skip". See `docs/readme/ready-for-review.md` for the full checklist semantics. --> - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I've included tests if applicable - [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### Performance checks (if applicable) - [ ] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [ ] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [ ] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** <!-- Reviewer checklist items follow the same semantics as the author checklist: an unchecked box is ambiguous, a checked box means the reviewer consciously assessed that responsibility. See `docs/readme/ready-for-review.md`. --> - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Adds a repo-wide `.npmrc` that changes dependency-install behavior (disables lifecycle scripts and forces offline/cache-only installs), which can break installs in CI/dev environments if assumptions differ. > > **Overview** > Adds a committed `.npmrc` configuring npm to `ignore-scripts`, disable auto-`yes`, and run in `offline` mode. > > Updates `.gitignore` to stop excluding `.npmrc`, so these npm defaults are versioned and applied consistently across the project. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit d54246b. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until this PR meets the canonical
Definition of Ready For Review in `docs/readme/ready-for-review.md`.
In short: the template must be materially complete (not just section
titles
present), all status checks must be currently passing, and the only
expected
follow-up commits must be reviewer-driven.
-->
## **Description**
Replaces the branch-keyed `cirruslabs/cache` reuse layer for native E2E
builds with a content-addressable cross-run lookup, driven by a
`build-source-hash` commit status that is computed once on a stable
runner.
### How it works
```mermaid
flowchart TD
A["post-build-source-hash<br/>(ubuntu-latest, pinned to PR head SHA)<br/>fingerprint = yarn fingerprint:generate"] -->|posts build-source-hash status<br/>+ exposes as job output| B["Build iOS / Android job"]
B --> C{"check-force-builds<br/>label OR [force-builds] in commit?"}
C -- yes --> H["Heavy native-build path<br/>setup-e2e-env + Gradle/Xcode + compile"]
C -- no --> D["find-reusable-build<br/>(GitHub Actions REST API)"]
D --> D1["Tier 1: same-branch runs"]
D1 -- miss --> D2["Tier 2: base-branch (main) runs"]
D2 -- miss --> D3["Tier 3: cross-PR runs<br/>(event=pull_request, no branch filter)"]
D1 -- hit --> E["actions/download-artifact@v4<br/>by run-id"]
D2 -- hit --> E
D3 -- hit --> E
D3 -- miss --> H
E --> F["Lean repack path<br/>Node + yarn install + repack:{ios,android}"]
H --> I["Upload .app / release.apk / androidTest.apk"]
F --> I
I -.->|feeds future runs| D
```
The probe runs **before** any heavy setup. On a hit, iOS skips
Ruby/Bundler/CocoaPods/`pod install`; Android skips
`setup-e2e-env`/Gradle. Only the JS bundle is rebuilt and re-packed into
the cached native shell.
### Benefits vs the previous `cirruslabs/cache` layer
| | Before | After (this PR) |
|---|---|---|
| **Reuse keyspace** | `${ref_name}` baked into key → every PR isolated;
only `main → PR` fallback crossed branches | Content-addressable by
fingerprint; any PR can reuse any other PR's build |
| **When the lookup runs** | *After* `setup-e2e-env` (cache key needs
`node_modules` to compute fingerprint) | Before any heavy setup |
| **Fingerprint stability** | Recomputed per runner → drifts across
macOS / Linux build / Linux CI runners; shifts on every `main` push |
Computed once on `ubuntu-latest`, pinned to `pull_request.head.sha` |
| **iOS reuse-hit wall time** | ~6m setup + ~5m repack | ~30-60s setup +
~1-2m repack |
| **Android reuse-hit wall time** | ~5m23s | ~1-2m warm / ~2-3m
cold-cache |
| **Cold build (no reuse)** | ~20-25m | unchanged |
### What changed
- **`ci.yml`** — new `post-build-source-hash` job emits the canonical
fingerprint and exposes it as a job output consumed by both build jobs.
- **New composite actions** — `find-reusable-build` (3-tier scan),
`check-force-builds` (label + `[force-builds]` commit-message escape
hatch; reads commit message via REST API to survive shallow checkout),
`post-build-source-hash` (factored out for reuse).
- **`build-{ios,android}-e2e.yml`** — probe → gate → lean-repack vs
heavy-native paths. Lean paths skip the work `yarn build:repack:*`
doesn't need.
- **`setup-e2e-env`** — new `install-foundry` input (default `true`,
opt-out for build workflows where `yarn setup:github-ci` already runs
`install:foundryup`).
- **Repack throughput** — `METRO_MAX_WORKERS` bumped `2 → 6` on the lean
path (no Gradle/Xcode competing for RAM).
- **Removed** — branch- and main-scoped `cirruslabs/cache` for
`MetaMask.app` / `release.apk` / `release-androidTest.apk`. Gradle,
Xcode DerivedData, and `.metamask` caches kept (gated to the heavy
path).
### Safety
- Fingerprint job failure or forked PR (no `statuses: write`) → empty
`source-fingerprint` → all reuse steps skipped → fresh build runs. Never
"no build".
- The same `build-source-hash` status gates the OTA path in
`push-eas-update.yml`, so a JS-only OTA cannot ship after native code
changes.
- Full architecture, decision tables, and failure-mode catalog:
`docs/ci-build-reuse.md` (new in this PR).
## **Changelog**
CHANGELOG entry: null
## **Related issues**
Refs: Prior art in MetaMask extension —
MetaMask/metamask-extension#41435
No issue: CI infrastructure improvement; no Jira ticket.
## **Manual testing steps**
```gherkin
Feature: Reusable native E2E builds on CI
Scenario: Fresh run populates the reuse pool
Given this branch has no prior completed CI run with a matching fingerprint
When CI runs on the latest commit
Then post-build-source-hash posts a build-source-hash commit status on the PR head SHA
And Build iOS E2E Apps runs setup-e2e-env and the full Xcode native compile
And Build Android E2E APKs runs setup-e2e-env and the full Gradle build
And both jobs upload artifacts named ${build_type}-${env}-MetaMask.app, ${build_type}-${env}-release.apk, and ${build_type}-${env}-release-androidTest.apk
Scenario: Empty commit reuses the prior native build (same-branch tier)
Given the branch has a prior successful run with non-expired artifacts
When an empty commit is pushed
Then post-build-source-hash computes and posts the same fingerprint as before
And find-reusable-build reports a hit via the same-branch tier
And Build iOS E2E Apps skips Ruby/Bundler/CocoaPods/Xcode setup and only runs yarn build:repack:ios
And Build Android E2E APKs skips setup-e2e-env and only runs yarn build:repack:android
And E2E tests run against the repacked artifacts
Scenario: Cross-PR reuse finds an unrelated PR with matching fingerprint
Given PR A on branch feature-a completed a fresh native build and uploaded artifacts
And PR B on branch feature-b touches only JS/tests/docs (no native-affecting files)
When PR B's CI runs
Then find-reusable-build misses the same-branch tier (feature-b runs)
And misses the base-branch tier (no recent main run with the matching fingerprint)
And matches PR A's run via the cross-PR tier (event=pull_request, no branch filter)
And PR B downloads PR A's artifacts by run-id and runs yarn build:repack:*
Scenario: force-builds label bypasses reuse
Given a PR that would otherwise hit the reuse path
When the force-builds label is added and CI re-runs
Then check-force-builds reports force=true
And find-reusable-build does not run
And both iOS and Android run a fresh native compile
And when the label is removed and CI re-runs, reuse resumes normally
Scenario: [force-builds] commit tag bypasses reuse under shallow checkout
Given a PR whose head commit message contains [force-builds]
When CI runs
Then check-force-builds reads the commit message via the GitHub REST API (not git show)
And reports force=true even with actions/checkout's default fetch-depth: 1
And both iOS and Android run a fresh native compile
Scenario: Fingerprint job failure degrades gracefully to fresh build
Given post-build-source-hash fails (e.g. broken fingerprint.config.js, transient yarn install error, or missing statuses: write on a fork)
When the build workflows run
Then inputs.source-fingerprint is empty
And every fingerprint-keyed step is skipped
And both iOS and Android run a fresh native compile
And no E2E build is blocked
Scenario: Metro transform cache persists across repack runs
Given a reuse hit on the repack path
When yarn build:repack:{ios,android} runs
Then Metro uses METRO_CACHE_DIR as its FileStore root
And the persisted transform cache is honored (no --reset-cache)
And the E2E build runs with updates disabled (no app.manifest generation)
```
## **Screenshots/Recordings**
### **Before**
N/A — CI-only change; no UI impact.
### **After**
N/A — CI-only change; no UI impact.
## **Pre-merge author checklist**
- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
#### Performance checks (if applicable)
- [x] I've tested on Android
- [x] I've tested with a power user scenario
- [x] I've instrumented key operations with Sentry traces for production
performance metrics
For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
<!-- Generated with the help of the pr-description AI skill -->
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Changes CI build/reuse logic and caching paths for iOS/Android E2E
artifacts, which could cause unexpected stale/invalid artifacts or
missed rebuilds if the fingerprint/status or artifact lookup is wrong.
Scoped to CI/workflows, but failures can block or slow builds across
PRs.
>
> **Overview**
> Enables **cross-run, cross-PR reuse** of native E2E build artifacts by
introducing a canonical `@expo/fingerprint` published as a
`build-source-hash` commit status and using it to locate/download
matching artifacts from prior workflow runs.
>
> Build workflows now **gate between a full native build vs a lean
repack path**: they first check a `force-builds` override (PR label or
`[force-builds]` commit token), then attempt to find/download reusable
artifacts; on a hit they skip heavy setup (Gradle/Xcode) and only run
repack + lightweight dependency setup.
>
> CI wiring is updated to add the `post-build-source-hash` job and pass
`source-fingerprint` into iOS/Android build jobs (with added
`actions/statuses/pull-requests` read permissions), `setup-e2e-env`
gains an `install-foundry` toggle to avoid redundant installs, and
repack throughput is tuned (e.g., `METRO_MAX_WORKERS` increased on reuse
paths) with clearer guidance when repack detects a broken cached iOS
app.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
89e6bc5. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**
This PR adds minimal Predict confirmation hook plumbing needed by the
upcoming Polymarket Deposit Wallet migration.
It wires TransactionController confirmation lifecycle hooks to
PredictController while keeping Predict behavior as passthrough by
default:
- `beforePublish` delegates to `PredictController.beforePublish`, which
currently returns `true`.
- `publish` delegates to `PredictController.publish` before Transaction
Pay / 7702 / Smart Transactions, and continues normal publishing when
Predict returns no transaction hash.
- If a future Predict publish implementation returns `{ transactionHash,
isIntentComplete: true }`, TransactionController marks the latest
transaction meta as `isIntentComplete` before returning the hash.
This PR intentionally contains no Polymarket Deposit Wallet business
logic. It is a small foundation PR for confirmation-team review.
## **Changelog**
CHANGELOG entry: null
## **Related issues**
Fixes: N/A — preparatory plumbing for the Predict Deposit Wallet
migration.
## **Manual testing steps**
```gherkin
Feature: Predict confirmation hook plumbing
Scenario: non-Predict transactions continue through the normal publish flow
Given a transaction is published through TransactionController
And PredictController.publish returns no transaction hash
When the publish hook runs
Then Transaction Pay / 7702 / Smart Transaction publishing continues as before
Scenario: Predict publish can complete a transaction intent
Given PredictController.publish returns a transaction hash and isIntentComplete
When the publish hook runs
Then normal publishing is short-circuited
And the latest TransactionController transaction meta is marked intent complete
```
Local validation run:
```bash
yarn jest app/core/Engine/controllers/transaction-controller/transaction-controller-init.test.ts app/components/UI/Predict/controllers/PredictController.test.ts --runInBand
yarn lint:tsc
```
## **Screenshots/Recordings**
N/A — no UI changes.
### **Before**
N/A
### **After**
N/A
## **Pre-merge author checklist**
- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
#### Performance checks (if applicable)
- [x] I've tested on Android
- N/A — hook plumbing only, no UI/runtime performance path manually
exercised.
- [x] I've tested with a power user scenario
- N/A — hook plumbing only, no account/token rendering path changed.
- [x] I've instrumented key operations with Sentry traces for production
performance metrics
- N/A — this PR only adds passthrough hook plumbing.
For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Touches transaction publishing lifecycle by adding new hooks and a
short-circuit path, which could affect submission ordering and
integration with Pay/7702/Smart Transactions if miswired. Default
behavior remains passthrough, reducing blast radius.
>
> **Overview**
> Adds Predict-specific confirmation hook plumbing into the transaction
submission lifecycle. TransactionController init now calls
`PredictController:beforePublish` as a new `hooks.beforePublish`, and
calls `PredictController:publish` at the start of `hooks.publish`,
**short-circuiting** the rest of the publish pipeline when Predict
returns a `transactionHash`.
>
> Updates PredictController to expose new messenger methods
(`beforePublish`, `publish`) with default passthrough implementations,
extends messenger action typings/permissions accordingly, and adds unit
tests verifying delegation, call ordering, and the short-circuit
behavior.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
3f9d618. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until this PR meets the canonical Definition of Ready For Review in `docs/readme/ready-for-review.md`. In short: the template must be materially complete (not just section titles present), all status checks must be currently passing, and the only expected follow-up commits must be reviewer-driven. --> ## **Description** <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> This PR is a follow-up to the BN.js to native `BigInt` burndown effort called out in [this Slack post](https://consensys.slack.com/archives/C02U025CVU4/p1777911707412459). In the design-system-owned `AggregatedPercentage` area, it completes the remaining `app/util/number/index.js` migration by switching `AggregatedPercentage/utils.ts` to `app/util/number/bigint`, removing the migrated path from `utilNumberImportBurndownFiles`, and deleting the stale migration-guide entry. While doing that cleanup, it also removes the unused `AggregatedPercentage` component, its dead story/test/export surface, and the type dependency that kept `useMultichainBalances` coupled to the deleted file. The live hook now uses a local `AggregatedBalance` interface instead. ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: null ## **Related issues** No issue: maintenance-only BN.js to BigInt burndown follow-up prompted by the internal migration announcement. ## **Manual testing steps** ```gherkin Feature: AggregatedPercentage bigint migration cleanup Scenario: validate remaining AggregatedPercentage consumers after migration Given the AggregatedPercentage dead component has been removed When I run the AggregatedPercentage and balance change Jest suites Then all related tests should pass using the BigInt-backed renderFiat import ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** N/A ### **After** N/A ## **Pre-merge author checklist** <!-- Every checklist item must be consciously assessed before marking this PR as "Ready for review". A checked box means you deliberately considered that responsibility, not that you literally performed every action listed. Unchecked boxes are ambiguous: they are not an implicit "N/A" and they are not a silent "skip". See `docs/readme/ready-for-review.md` for the full checklist semantics. --> - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### Performance checks (if applicable) - [x] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [x] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [x] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** <!-- Reviewer checklist items follow the same semantics as the author checklist: an unchecked box is ambiguous, a checked box means the reviewer consciously assessed that responsibility. See `docs/readme/ready-for-review.md`. --> - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- Generated with the help of the pr-description AI skill --> <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk maintenance: removes unused UI component/story/test and tightens types; the only functional change is switching `AggregatedPercentage/utils.ts` to the BigInt-backed `renderFiat`, which could slightly affect formatting if any remaining caller relies on legacy behavior. > > **Overview** > Removes the unused `AggregatedPercentage` component surface (component file, types, index export), along with its Storybook story and Jest test, and drops its story registration. > > Completes remaining BN.js→BigInt cleanup in this area by switching `AggregatedPercentage/utils.ts` to import `renderFiat` from `app/util/number/bigint`, updating ESLint’s legacy `util/number` allowlist and pruning the corresponding entry from `docs/bigint-migration-guide.md`. The `useMultichainBalances` hook types are decoupled from the deleted component by introducing a local `AggregatedBalance` interface and returning it from `getAggregatedBalance`. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit feb0864. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until this PR meets the canonical
Definition of Ready For Review in `docs/readme/ready-for-review.md`.
In short: the template must be materially complete (not just section
titles
present), all status checks must be currently passing, and the only
expected
follow-up commits must be reviewer-driven.
-->
## **Description**
**Reason:** The Bridge feature stack used JavaScript-based
`@react-navigation/stack`, which differs from native stack behavior
elsewhere and relied on `navigation.setOptions` plus compact header
helpers for several screens.
**Solution:**
- Bridge and Bridge modal navigators now use
`@react-navigation/native-stack`. Stack screens hide the default React
Navigation header (`headerShown: false`). Titles and back actions are
rendered in-screen with `HeaderStandard` from the design system, wrapped
with `SafeAreaView` so top insets stay correct.
- `ScreenView` gains an optional `safeAreaEdges` prop (default
unchanged) so screens that already apply bottom/left/right safe area in
an outer wrapper can pass `safeAreaEdges={[]}` and avoid double padding.
**For reviews** please view the files with this link
https://github.com/MetaMask/metamask-mobile/pull/29829/changes?w=1
because a lot of changes in
app/components/UI/Bridge/Views/BridgeView/index.tsx are just formatting
## **Changelog**
<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`
If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`
(This helps the Release Engineer do their job more quickly and
accurately)
-->
CHANGELOG entry: Updated Bridge navigation to use the native stack with
in-screen headers for Bridge, token selection, and quote selection.
## **Related issues**
Fixes:
## **Manual testing steps**
```gherkin
Feature: Bridge native stack and inline headers
Scenario: Open Bridge and use the inline header
Given the user is on a wallet account with Bridge available
When the user opens Bridge from the app
Then the Bridge screen shows the correct title (Bridge, Swaps, or combined per mode) and a working back control
Scenario: Token selector header and safe area
Given the user is on the Bridge screen
When the user opens the source or destination token selector
Then the token selector shows the "Select token" title, back returns to Bridge, and content is not clipped by device safe areas
Scenario: Quote selector header
Given the user is on Bridge with valid quotes
When the user opens the quote selector
Then the quote selector shows the "Select quote" title and back returns to the previous Bridge step
Scenario: Bridge modals still present as overlays
Given the user is on Bridge
When the user opens a Bridge modal (e.g. slippage or network list, as applicable)
Then the modal still presents with expected transparent overlay behavior
```
## **Screenshots/Recordings**
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->
### **Before**
https://github.com/user-attachments/assets/ce10fe39-db04-42dd-830e-4c908c38d76e
https://github.com/user-attachments/assets/72d0539f-d554-47e2-99a4-79f47df34f50
<!-- [screenshots/recordings] -->
### **After**
https://github.com/user-attachments/assets/b6f4c3ea-5e2e-4d77-92d6-a561ad4db79f
https://github.com/user-attachments/assets/3f2acc31-b4c4-4418-81e9-4da313f59ec5
<!-- [screenshots/recordings] -->
## **Pre-merge author checklist**
<!--
Every checklist item must be consciously assessed before marking this PR
as
"Ready for review". A checked box means you deliberately considered that
responsibility, not that you literally performed every action listed.
Unchecked boxes are ambiguous: they are not an implicit "N/A" and they
are not
a silent "skip". See `docs/readme/ready-for-review.md` for the full
checklist
semantics.
-->
- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
#### Performance checks (if applicable)
- [x] I've tested on Android
- Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example
For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).
## **Pre-merge reviewer checklist**
<!--
Reviewer checklist items follow the same semantics as the author
checklist: an
unchecked box is ambiguous, a checked box means the reviewer consciously
assessed that responsibility. See `docs/readme/ready-for-review.md`.
-->
- [x] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [x] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Navigation for Bridge screens is refactored to native-stack and moves
headers into screen layouts, which can subtly affect transitions,
safe-area insets, and back behavior across platforms. Risk is moderate
because changes are mostly UI/navigation but touch multiple entry
screens and modal presentation options.
>
> **Overview**
> Bridge navigation is migrated from JS `@react-navigation/stack` to
`@react-navigation/native-stack`, hiding the default navigator header
and rendering in-screen headers via design-system `HeaderStandard` for
`BridgeView`, `BridgeTokenSelector`, and `QuoteSelectorView`.
>
> To support this, `ScreenView` now accepts `safeAreaEdges` (defaulting
to bottom/left/right) so screens that wrap themselves in an outer
`SafeAreaView` can disable internal insets (`safeAreaEdges={[]}`) and
avoid double padding; Bridge screens also add wrapper styles to ensure
correct background/safe-area handling.
>
> Tests are updated to assert inline header rendering (instead of
`navigation.setOptions`) and to adjust mocks/selectors to avoid
`ButtonIcon` testID collisions with the new back button.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
3a898d1. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description** This is PR 2 for the Predict Deposit Wallet migration and is temporarily opened against `predict/dw-confirmation-hooks` to accelerate review while PR 1 is reviewed. Once PR 1 merges, this PR should be rebased/retargeted to `main`. Polymarket migrated new API users from the legacy Safe/proxy wallet model to deterministic Deposit Wallets. This PR adds the shared Predict Deposit Wallet foundation and enables the deposit flow while preserving legacy Safe behavior for users with existing Polymarket activity. Included changes: - Adds `walletType` to Predict account state and routes users by legacy Safe activity: - legacy Safe with raw Polymarket activity stays on Safe - legacy Safe without activity routes to Deposit Wallet - deployed legacy Safe + Activity API failure fails closed - Adds Deposit Wallet helper utilities for deterministic address derivation, relayer proxy calls, polling, EIP-712 batch execution, and CLOB balance-allowance sync. - Adds Deposit Wallet deposit preflight to deploy/setup allowances in `beforePublish`. - Adds legacy Safe migration sweep planning for zero-activity users with stranded pUSD/USDC.e. - Updates deposit preparation so Deposit Wallet users receive pUSD transfers to their Deposit Wallet. - Updates balance/position lookup to use the active Predict wallet. - Adds post-confirm best-effort CLOB balance-allowance sync for Deposit Wallet deposits and deposit-and-order deposits. - Keeps order and claim execution support out of scope for this PR; those follow in separate PRs. Validation performed: - `yarn jest app/components/UI/Predict/providers/polymarket/depositWallet.test.ts app/components/UI/Predict/providers/polymarket/preflight/legacySafeMigration.test.ts app/components/UI/Predict/providers/polymarket/preflight/depositWallet.test.ts app/components/UI/Predict/providers/polymarket/preflight/v2AllowanceRequirements.test.ts app/components/UI/Predict/providers/polymarket/PolymarketProvider.test.ts app/components/UI/Predict/controllers/PredictController.test.ts app/components/UI/Predict/hooks/usePredictAccountState.test.ts --runInBand --forceExit` - `yarn lint:tsc` ## **Changelog** CHANGELOG entry: Added support for Polymarket Deposit Wallet deposits in Predict ## **Related issues** Fixes: [PRED-858](https://consensyssoftware.atlassian.net/browse/PRED-858) ## **Manual testing steps** ```gherkin Feature: Predict Deposit Wallet deposits Scenario: new Predict user deposits to a Polymarket Deposit Wallet Given the selected wallet has no legacy Safe Polymarket activity And the user opens Predict deposit When user confirms a Predict deposit Then the Deposit Wallet setup preflight runs through the relayer And the pUSD deposit transaction transfers funds to the derived Deposit Wallet And the deposit completes without changing legacy Safe users' behavior ``` ```gherkin Feature: Legacy Safe compatibility Scenario: existing Predict user with legacy Safe activity deposits Given the selected wallet has a deployed legacy Safe with Polymarket activity When user prepares a Predict deposit Then Predict keeps using the legacy Safe path And no Deposit Wallet relayer preflight is run ``` ## **Screenshots/Recordings** N/A — core/provider flow changes covered by tests and manual wallet-flow validation. ### **Before** N/A ### **After** N/A ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### Performance checks (if applicable) - [ ] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [ ] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [ ] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. [PRED-858]: https://consensyssoftware.atlassian.net/browse/PRED-858?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **High Risk** > High risk because it changes how Predict chooses deposit addresses and adds new pre-publish relayer/batch execution plus post-confirm sync, which directly affects deposit and deposit+order transaction flows and fund routing. > > **Overview** > Adds first-class support for Polymarket **Deposit Wallet** accounts in Predict by extending `AccountState` with `walletType` and routing users to either legacy Safe or a deterministic deposit wallet based on legacy Safe deployment and Polymarket Activity API results (failing closed on API errors). > > Implements deposit-wallet infrastructure in the Polymarket provider: deterministic address derivation, relayer proxy calls/polling, EIP-712 batch execution, allowance-preflight planning (excluding Permit2), and a legacy Safe “sweep” preflight to migrate stranded USDC.e/pUSD to the deposit wallet. > > Updates the deposit pipeline to (1) build deposits targeting the deposit wallet (with optional sweep), (2) run a new `beforePublish` deposit-wallet preflight to ensure wallet deployment and required allowances, and (3) on confirmed deposits/deposit+order, invalidate cached account state and best-effort sync CLOB balance/allowance—waiting for that sync before placing the follow-on order. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit c5f61e2. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until this PR meets the canonical
Definition of Ready For Review in `docs/readme/ready-for-review.md`.
In short: the template must be materially complete (not just section
titles
present), all status checks must be currently passing, and the only
expected
follow-up commits must be reviewer-driven.
-->
## **Description**
Three bugs were identified and fixed in the `update-e2e-fixtures.yml`
workflow, which is triggered by commenting `@metamaskbot
update-mobile-fixture` on a PR.
**1. `dispatch` job failed with HTTP 403 when triggering
`workflow_dispatch`**
`issue_comment` events run from the default branch (`main`) with a
`GITHUB_TOKEN` that has read-only permissions by default. Calling `gh
workflow run` (which requires `actions: write`) and `gh pr comment`
(which requires `pull-requests: write`) with that token caused a 403.
Fixed by adding an explicit `permissions` block to the `dispatch` job
(`actions: write`, `contents: read`, `pull-requests: write`).
**2. iOS app artifact consistently failed to restore from cache**
The `prepare` job (running on `ubuntu-latest`) was saving the iOS `.app`
artifact to GitHub Actions cache, and the `update-fixtures` job (running
on `ghcr.io/cirruslabs/macos-runner:tahoe`) was trying to restore it.
The Cirrus Labs macOS runner does not reliably support GitHub Actions
cache restoration across jobs, causing a persistent `fail-on-cache-miss`
failure. Fixed by removing the cache entirely: `prepare` now validates
the CI run and exposes the `RUN_ID` as a job output; `update-fixtures`
downloads the artifact directly using `gh run download` with the
`GITHUB_TOKEN`, which uses the GitHub API and works on any runner with
network access.
**3. Misleading "No E2E fixture changes detected" comment posted on
failure**
When `update-fixtures` failed (e.g., at the cache restore step), the
`Cache updated fixture` step still ran due to its `if: ${{ !cancelled()
}}` condition, saving the unmodified fixture to cache.
`commit-updated-fixtures` then restored that stale fixture, saw no diff,
and posted a false success comment. Fixed by:
- Removing `if: ${{ !cancelled() }}` from `Cache updated fixture` so it
only runs when all prior steps succeed.
- Adding `needs.update-fixtures.result == 'success'` to
`commit-updated-fixtures`'s condition so it skips entirely when the
fixture job failed, allowing `failure-comment` to post the correct error
message instead.
<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->
## **Changelog**
<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`
If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`
(This helps the Release Engineer do their job more quickly and
accurately)
-->
CHANGELOG entry:
## **Related issues**
Fixes:
## **Manual testing steps**
N/A
## **Screenshots/Recordings**
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->
### **Before**
N/A
<!-- [screenshots/recordings] -->
### **After**
N/A
<!-- [screenshots/recordings] -->
## **Pre-merge author checklist**
<!--
Every checklist item must be consciously assessed before marking this PR
as
"Ready for review". A checked box means you deliberately considered that
responsibility, not that you literally performed every action listed.
Unchecked boxes are ambiguous: they are not an implicit "N/A" and they
are not
a silent "skip". See `docs/readme/ready-for-review.md` for the full
checklist
semantics.
-->
- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
#### Performance checks (if applicable)
- [ ] I've tested on Android
- Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example
For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).
## **Pre-merge reviewer checklist**
<!--
Reviewer checklist items follow the same semantics as the author
checklist: an
unchecked box is ambiguous, a checked box means the reviewer consciously
assessed that responsibility. See `docs/readme/ready-for-review.md`.
-->
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Modifies the `update-e2e-fixtures` GitHub Actions workflow execution
and artifact retrieval logic; failures could block or misreport fixture
updates, but changes are confined to CI automation.
>
> **Overview**
> Fixes the `update-e2e-fixtures` workflow so the bot-triggered run has
the required GitHub token permissions and more reliably targets the
correct CI artifacts.
>
> `prepare` now validates the latest `ci` run for the PR branch/HEAD and
exposes its `RUN_ID`, and `update-fixtures` downloads the iOS `.app`
artifact directly from that run (removing the cross-runner cache-based
artifact transfer).
>
> Tightens job gating so fixture caching/committing only happens after a
successful `update-fixtures` run, and switches fixture formatting to use
repo `yarn prettier` (with Node/yarn cache + install) instead of
installing `prettier` ad-hoc.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
03ce80d. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until this PR meets the canonical Definition of Ready For Review in `docs/readme/ready-for-review.md`. In short: the template must be materially complete (not just section titles present), all status checks must be currently passing, and the only expected follow-up commits must be reviewer-driven. --> ## **Description** <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> These changes removes most QA workflows, variants, and conditions related to builds ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/MCWP-591 ## **Manual testing steps** ```gherkin Feature: my feature name Scenario: user [verb for user action] Given [describe expected initial app state] When user [verb for user action] Then [describe expected outcome] ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** <!-- Every checklist item must be consciously assessed before marking this PR as "Ready for review". A checked box means you deliberately considered that responsibility, not that you literally performed every action listed. Unchecked boxes are ambiguous: they are not an implicit "N/A" and they are not a silent "skip". See `docs/readme/ready-for-review.md` for the full checklist semantics. --> - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I've included tests if applicable - [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### Performance checks (if applicable) - [ ] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [ ] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [ ] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** <!-- Reviewer checklist items follow the same semantics as the author checklist: an unchecked box is ambiguous, a checked box means the reviewer consciously assessed that responsibility. See `docs/readme/ready-for-review.md`. --> - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Medium risk because it removes the `qa` build target across CI and native projects, which can break builds/tests or artifact expectations if any remaining jobs or external tooling still reference QA outputs. > > **Overview** > **Removes the QA build variant/target across the repo and standardizes CI on `main`/`flask` + `e2e` env.** GitHub Actions E2E build/test workflows drop `keystore_target`/`qa` defaults and update `metamask_environment` defaults to `e2e`. > > Android build config removes the `qa` flavor, QA signing config, and QA-specific Google Services and resources, and tightens NDK path selection to production only. iOS drops the `MetaMask-QA` target/scheme and related export options/plists, and CocoaPods config is updated accordingly. > > Build scripts and tooling (`scripts/build.sh`, `metro.transform.js`, `scripts/rename-artifacts.js`, `package.json`) remove `qa` handling/commands and adjust Sentry properties selection to be environment-based (production vs non-production). Docs are updated to remove legacy QA/Appium references and point BrowserStack upload instructions to GitHub Actions artifacts. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 88d2e04. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until this PR meets the canonical Definition of Ready For Review in `docs/readme/ready-for-review.md`. In short: the template must be materially complete (not just section titles present), all status checks must be currently passing, and the only expected follow-up commits must be reviewer-driven. --> ## **Description** <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> These changes removes most QA workflows, variants, and conditions related to builds ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/MCWP-591 ## **Manual testing steps** ```gherkin Feature: my feature name Scenario: user [verb for user action] Given [describe expected initial app state] When user [verb for user action] Then [describe expected outcome] ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** <!-- Every checklist item must be consciously assessed before marking this PR as "Ready for review". A checked box means you deliberately considered that responsibility, not that you literally performed every action listed. Unchecked boxes are ambiguous: they are not an implicit "N/A" and they are not a silent "skip". See `docs/readme/ready-for-review.md` for the full checklist semantics. --> - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I've included tests if applicable - [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### Performance checks (if applicable) - [ ] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [ ] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [ ] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** <!-- Reviewer checklist items follow the same semantics as the author checklist: an unchecked box is ambiguous, a checked box means the reviewer consciously assessed that responsibility. See `docs/readme/ready-for-review.md`. --> - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Medium risk because it removes the `qa` build target across CI and native projects, which can break builds/tests or artifact expectations if any remaining jobs or external tooling still reference QA outputs. > > **Overview** > **Removes the QA build variant/target across the repo and standardizes CI on `main`/`flask` + `e2e` env.** GitHub Actions E2E build/test workflows drop `keystore_target`/`qa` defaults and update `metamask_environment` defaults to `e2e`. > > Android build config removes the `qa` flavor, QA signing config, and QA-specific Google Services and resources, and tightens NDK path selection to production only. iOS drops the `MetaMask-QA` target/scheme and related export options/plists, and CocoaPods config is updated accordingly. > > Build scripts and tooling (`scripts/build.sh`, `metro.transform.js`, `scripts/rename-artifacts.js`, `package.json`) remove `qa` handling/commands and adjust Sentry properties selection to be environment-based (production vs non-production). Docs are updated to remove legacy QA/Appium references and point BrowserStack upload instructions to GitHub Actions artifacts. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 88d2e04. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description** Adds Predict order placement support for Polymarket Deposit Wallet accounts on top of the Deposit Wallet deposit foundation. This PR: - Adds the `POLY_1271` Polymarket signature type. - Adds Deposit Wallet / ERC-1271 order signing via the `TypedDataSign` wrapper. - Routes order maker/signer fields from active Predict account state. - Uses Deposit Wallet maker/signer for Deposit Wallet users. - Preserves legacy Safe order signing for grandfathered Safe users. - Runs Deposit Wallet create/setup preflight before submitting Deposit Wallet orders. - Passes an optional signed legacy Safe migration sweep as `allowancesTx` for Deposit Wallet orders, so stranded pUSD/USDC.e can be swept before the backend relays the order. - Skips Safe trade allowance and Permit2 fee preflight for Deposit Wallet orders. - Continues signing CLOB L2 headers with the EOA owner address. This PR is temporarily stacked on `predict/dw-deposit-foundation` while PRs 1 and 2 are under review, and should be rebased/retargeted after those merge. Validation run locally: ```bash yarn jest app/components/UI/Predict/providers/polymarket/protocol/orderCodec.test.ts app/components/UI/Predict/providers/polymarket/PolymarketProvider.test.ts --runInBand yarn lint:tsc ``` ## **Changelog** CHANGELOG entry: Fixed Predict order placement for Polymarket Deposit Wallet accounts ## **Related issues** Fixes: [PRED-860](https://consensyssoftware.atlassian.net/browse/PRED-860) ## **Manual testing steps** ```gherkin Feature: Predict Deposit Wallet order flow Scenario: Deposit Wallet user places a Predict order Given a Predict user is routed to a Polymarket Deposit Wallet And the Deposit Wallet has enough pUSD balance and required setup from the deposit flow When the user places a Predict buy or sell order Then the order is signed with POLY_1271 semantics And the order is submitted successfully to the Polymarket CLOB Scenario: Deposit Wallet user places first order before wallet setup Given a Predict user is routed to a Polymarket Deposit Wallet And the Deposit Wallet still needs creation or allowance setup When the user places a Predict buy or sell order Then the app creates/sets up the Deposit Wallet before order submission And the order is submitted successfully to the Polymarket CLOB Scenario: Deposit Wallet user has funds stranded in legacy Safe Given a Predict user is routed to a Polymarket Deposit Wallet And the deterministic legacy Safe has sweepable pUSD or USDC.e When the user places a Predict buy or sell order Then the signed legacy Safe sweep is included as allowancesTx And the backend can submit the sweep before relaying the order Scenario: Legacy Safe user places a Predict order Given a Predict user is grandfathered to the legacy Safe wallet When the user places a Predict buy or sell order Then the order continues to use legacy Safe signing and preflight behavior ``` ## **Screenshots/Recordings** ### **Before** N/A - provider/order-signing change only. ### **After** N/A - provider/order-signing change only. ## **Pre-merge author checklist** - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I've included tests if applicable - [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### Performance checks (if applicable) - [ ] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [ ] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [ ] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. [PRED-860]: https://consensyssoftware.atlassian.net/browse/PRED-860?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes core Predict order submission/signing paths, adding a new ERC-1271 signing format and deposit-wallet preflight flows; mistakes could cause failed or incorrectly-signed orders. Legacy Safe behavior is preserved but now shares more conditional branching. > > **Overview** > Adds end-to-end order placement support for Polymarket **Deposit Wallet** accounts. > > Order submission now derives maker/signer from the resolved account state and, for deposit-wallet users, performs a create/allowance batch preflight before signing/submitting. Deposit-wallet orders use the new `SignatureType.POLY_1271` and are signed via `signProtocolOrder` using an ERC-7739 `TypedDataSign` wrapper, while Safe users keep legacy Safe signing. > > Fee collection and Safe trade preflight steps (Permit2 fee authorization + allowances tx) are skipped for deposit-wallet orders; instead an optional legacy Safe migration sweep can be attached as `allowancesTx`. L2 CLOB headers are consistently signed using the EOA owner address. Tests were expanded to cover both Safe and deposit-wallet order flows and the new signing payload. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit b2bf1ee. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
See Commits and Changes for more details.
Created by
pull[bot] (v2.0.0-alpha.4)
Can you help keep this open source service alive? 💖 Please sponsor : )